// import com.alibaba.druid.sql.ast.SQLExpr;
// import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
// import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
// import com.alibaba.druid.sql.visitor.SQLEvalVisitor;

// import java.text.SimpleDateFormat;
// import java.util.Date;
// import java.util.List;

// import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_ERROR;
// import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;

#include "ToChar.h"
#include "../SQLEvalVisitor.h"

ToChar *ToChar::instance()
{
  static ToChar x;
  return &x;
}
// static final ToChar instance = new ToChar();

Object_ptr ToChar::eval(SQLEvalVisitor *visitor, SQLMethodInvokeExpr *x)
{
  SQLExpr_list_ptr arguments = x->getArguments();
  if (arguments->size() != 2)
  {
    return SQLEvalVisitor::EVAL_ERROR;
  }

  for (SQLExpr_ptr arg : *arguments)
  {
    arg->accept(SQLEvalVisitor_ptr(visitor));
  }

  auto it_arguments = arguments->begin();
  std::advance(it_arguments, 0);
  auto v0_ = (*it_arguments)->getAttributes()->find(SQLEvalVisitor::EVAL_VALUE->c_str());
  Object_ptr v0 = nullptr;
  if (v0_ != (*it_arguments)->getAttributes()->end())
  {
    v0 = v0_->second;
  }
  std::advance(it_arguments, 1);
  auto v1_ = (*it_arguments)->getAttributes()->find(SQLEvalVisitor::EVAL_VALUE->c_str());
  Object_ptr v1 = nullptr;
  if (v1_ != (*it_arguments)->getAttributes()->end())
  {
    v1 = v1_->second;
  }
  if (v0 != nullptr && v1 != nullptr && v0->getType() == Object::ParamType::LONG && v1->getType() == Object::ParamType::STRING)
  {
    time_t date = ((time_t)v0->getLong());

    std::string format = v1->getString();
    if (format == "yyyymmdd")
    {
      // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
      // return dateFormat.format(date);

      std::string myFormat = "%Y%m%d";
      struct tm *myt = localtime(&date);
      char myStr[255] = "\0";
      strftime(myStr, sizeof(myStr), myFormat.c_str(), myt);
      return Object_ptr(new Object(myStr));
    }
  }

  return nullptr;
}
